﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using produccion.clases;
using System.Windows.Input;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using produccion.modelo;
using produccion.AccesoDatos;
using System.Diagnostics;
using System.Collections.Specialized;
using System.Data;


namespace produccion.vistamodelo
{
   public class VmRepNovedadConcepto: ViewModelBase, IDataErrorInfo
    {

        #region constructors
        
            public VmRepNovedadConcepto() 
            {
                try 
                {
                    lisProceso = selProceso.listarProcesos();
                    lisConceptos = new CLSCONCEP().listarConceptos();

                    _buscarConcepto = new VMbuscarGeneral((from cust in lisConceptos select new VMlistaGenerica
                        { strColumna1 = cust.CODCPT_CPT, strColumna2 = cust.NOMCPT_CPT }).ToList());
                    buscarConcepto.PropertyChanged += OnBuscarConceptosPropertyChanged;
                    buscarConcepto.gridBuscar.columna1.strNombre = "Codigo";
                    buscarConcepto.gridBuscar.columna2.strNombre = "Nombre";
                    buscarConcepto.gridBuscar.strTitulo = "Conceptos";

                    lisNovedadesPro.CollectionChanged += OnCollectionChanged;

                    if (MDOgeneral.conexion == null || MDOgeneral.conexion.State == ConnectionState.Closed)
                    {
                        MDOgeneral.conectar();
                    }
                    strTituloVentana = "Reporte de novedades por concepto - Usuario: " + MDOgeneral.usuario + " - [FrmRepNovedadConcepto]";
                }
                catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
       
            }

        #endregion

        #region fields
            private CLSSEMANAS _semana = new CLSSEMANAS {DESDE_SEM=DateTime.Today,HASTA_SEM=DateTime.Today};
            private ProcesoProduccionRepositorio _repositorio = new ProcesoProduccionRepositorio();
        #endregion

        #region public interfaces

            private string _strTituloVentana;
            public string strTituloVentana
            {
                get { return _strTituloVentana; }
                set { _strTituloVentana = value; base.OnPropertyChanged("strTituloVentana"); }
            }

            public int SEM_NVP 
            {
                get { return _semana.NROSEM_SEM; }
                set 
                { 
                    _semana.NROSEM_SEM = value;
                    consultarSemana("S");

                    lisCliente = selCliente.listaEmpleadosConEquipo(_semana.DESDE_SEM.Year.ToString(), _semana.NROSEM_SEM.ToString());//FJRF - Cargamos el listado de equipos con semana enviando la semana, el año

                    base.OnPropertyChanged("SEM_NVP"); 
                }
            }

            public DateTime dtDesde 
            {
                get { return _semana.DESDE_SEM; }
                set { _semana.DESDE_SEM=value; base.OnPropertyChanged("dtDesde"); }
            }

            public DateTime dtHasta
            {
                get { return _semana.HASTA_SEM; }
                set { 
                        _semana.HASTA_SEM = value;
                        consultarSemana("F");
                        base.OnPropertyChanged("dtHasta"); 
                    }
            }

            private int _numConsecutivo = 0;
            public int numConsecutivo
            {
                get { return _numConsecutivo; }
                set { _numConsecutivo = value; base.OnPropertyChanged("numConsecutivo"); }
            }

            private MDOgeneral.mensaje _msn = new MDOgeneral.mensaje();
            public MDOgeneral.mensaje msn 
            {
                get { return _msn; }
                set { _msn = value; base.OnPropertyChanged("msn");
                }
            }

            private List<CLSMAEEMPP> _lisCliente = new List<CLSMAEEMPP>();
            public List<CLSMAEEMPP> lisCliente 
            {
                get { return _lisCliente; }
                set { _lisCliente = value; base.OnPropertyChanged("lisCliente"); }
            }

            private CLSMAEEMPP _selCliente = new CLSMAEEMPP();
            public CLSMAEEMPP selCliente 
            {
                get { return _selCliente; }
                set { 
                        _selCliente = value;
                        if (_selCliente != null && _selProceso != null)
                        {
                            consultarNovedad();
                        }
                        base.OnPropertyChanged("selCliente"); 
                    }
            }

            private List<CLSPRCPRD> _lisProceso = new List<CLSPRCPRD>();
            public List<CLSPRCPRD> lisProceso 
            {
                get { return _lisProceso; }
                set { _lisProceso = value; base.OnPropertyChanged("lisProceso"); }
            }

            private CLSPRCPRD _selProceso = new CLSPRCPRD();
            public CLSPRCPRD selProceso
            {
                get { return _selProceso; }
                set { _selProceso = value; base.OnPropertyChanged("selProceso"); }
            }

            private VMbuscarGeneral _buscarConcepto;
            public VMbuscarGeneral buscarConcepto
            {
                get { return _buscarConcepto; }
                set { _buscarConcepto = value; base.OnPropertyChanged("buscarConcepto"); }
            }
       
            private List<CLSCONCEP> lisConceptos = new List<CLSCONCEP>();

            private ObservableCollection<VmNovedadProduccion> _lisNovedadesPro = new ObservableCollection<VmNovedadProduccion>();
            public ObservableCollection<VmNovedadProduccion> lisNovedadesPro 
            {
                get { return _lisNovedadesPro; }
                set { _lisNovedadesPro = value; base.OnPropertyChanged("lisNovedadesPro"); }
            }

            private VmNovedadProduccion _selNovedadesPro;
            public VmNovedadProduccion selNovedadesPro 
            {
                get { return _selNovedadesPro; }
                set { _selNovedadesPro = value; base.OnPropertyChanged("selNovedadesPro"); }
            }

            private List<CLSNOVPRD> _lisnovedades = new List<CLSNOVPRD>();
            public List<CLSNOVPRD> lisnovedades
            {
                get { return _lisnovedades; }
                set { _lisnovedades = value; base.OnPropertyChanged("lisnovedades"); }
            }

            private Boolean _logValido;
            public Boolean logValido
            {
                get { return _logValido; }
                set { _logValido = value; base.OnPropertyChanged("logValido"); }
            }

        #endregion

        #region commandos

            RelayCommand _cmdGuardar;
            public ICommand cmdGuardar
            {
                get
                {
                    if (_cmdGuardar == null)
                    {
                        _cmdGuardar = new RelayCommand(x => Guardar());
                    }
                    return _cmdGuardar;
                }
            }

            RelayCommand _cmdBuscarConcepto;
            public ICommand cmdBuscarConcepto
            {
                get
                {
                    if (_cmdBuscarConcepto == null)
                    {
                        _cmdBuscarConcepto = new RelayCommand(x => BuscarConcepto());
                    }
                    return _cmdBuscarConcepto;
                }
            }

            RelayCommand _cmdSalir;
            public ICommand cmdSalir
            {
                get
                {
                    if (_cmdSalir == null)
                    {
                        _cmdSalir = new RelayCommand(Salir);
                    }
                    return _cmdSalir;
                }
            }

        #endregion
        
        #region methods

            void consultarSemana(string sw)
            {
                try
                {
                    _semana = _repositorio.consultar_Semana(_semana, sw);
                    base.OnPropertyChanged("SEM_NVP");
                    base.OnPropertyChanged("dtDesde");
                    base.OnPropertyChanged("dtHasta");
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void consultarNovedad()
            {
                try
                {
                    int NumContador = 0;
                    numConsecutivo = _repositorio.consultarConsecutivoNovConcepto(_semana.HASTA_SEM, _semana.NROSEM_SEM, _selProceso.CODPRC_PPR, _selCliente.CODEMP_EMP);

                    lisnovedades = _repositorio.consultarNovedad(_semana.HASTA_SEM, _semana.NROSEM_SEM, _selProceso.CODPRC_PPR, _selCliente.CODEMP_EMP, "E", "XXX");

                    List<VmNovedadProduccion> all = (from nov in lisnovedades select new VmNovedadProduccion(nov)).ToList();
                    foreach (VmNovedadProduccion nv in all)
                    {
                        NumContador = NumContador + 1;
                        nv.validarNovedad += ValidateNovedad;
                        nv.PropertyChanged += OnPropertyChanged;
                    }
                    lisNovedadesPro = new ObservableCollection<VmNovedadProduccion>(all);
                    lisNovedadesPro.CollectionChanged += OnCollectionChanged;

                    if (NumContador == 0)
                        logValido = true;
                    else
                    {
                        if (numConsecutivo == NumContador && numConsecutivo>0)
                            numConsecutivo = 0;
                        else
                            numConsecutivo = numConsecutivo - 1;
                    }
                   
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }
            
            void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                try
                {
                    if (e.NewItems != null && e.NewItems.Count != 0)
                    {
                        //lisNovedadesPro.Last().CONSEC_NVP = (from nov in lisNovedadesPro orderby nov.CONSEC_NVP descending select nov.CONSEC_NVP).First() + 1;
                        lisNovedadesPro.Last().CONSEC_NVP = (from nov in lisNovedadesPro select nov).Count() + numConsecutivo;

                        foreach (VmNovedadProduccion nov in e.NewItems)
                        {
                            nov.PropertyChanged += OnPropertyChanged;
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            public void ValidateNovedad()
            {
                try
                {
                    logValido = !lisNovedadesPro.Any(x => x.IsValid == false);
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                try
                {
                    logValido = ((from nov in lisNovedadesPro where nov.IsValid.Equals(false) select nov.IsValid).ToList().Count()) > 0 ? true : false;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

            void Guardar() 
            {
                try 
                {
                    List<CLSNOVPRD> lstAgregar = (from nov in lisNovedadesPro where nov.agregar.Equals(true) select nov.getNovedades()).ToList();
                    List<CLSNOVPRD> lstActualizar = (from nov in lisNovedadesPro where nov.actualizar.Equals(true) select nov.getNovedades()).ToList();
                    List<CLSNOVPRD> lstEliminar = (from nov in lisNovedadesPro where nov.eliminar.Equals(true) select nov.getNovedades()).ToList();

                    if (_repositorio.guardarNovedadesConcepto(_semana.HASTA_SEM, _semana.NROSEM_SEM, _selProceso.CODPRC_PPR, _selCliente.CODEMP_EMP, "E", lstActualizar, lstEliminar, lstAgregar))
                    {
                        msn.texto = "La información de novedades se grabo exitosamente.";
                        msn.tipo = true;
                        limpiarNovedades();
                    }
                    else
                    {
                        msn.texto = "La información de novedades no se pudo grabar.";
                        msn.tipo = false;
                    }
                }
                catch (Exception ex){msn.texto = ex.Message; msn.tipo = false;}
            }

            void Salir(object _ventana) 
            {
                ((Window)_ventana).Close();
            }

            void BuscarConcepto()
            {
                try
                {
                    buscarConcepto.IsOpen = true;
                }
                catch (Exception ex) { msn.texto = ex.Message; msn.tipo = false; }
            }

            void OnBuscarConceptosPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                if (e.PropertyName == "IsOpen")
                {
                    if (!buscarConcepto.IsOpen)
                    {
                        if (buscarConcepto.gridBuscar.selLista != null)
                        {
                            if (selNovedadesPro != null)
                            {
                                selNovedadesPro.CODCPT_NVP = buscarConcepto.gridBuscar.selLista.strColumna1;
                            }
                        }
                    }
                }

            }

            void limpiarNovedades()
            {
                try
                {
                    lisNovedadesPro.Clear();
                    //selCliente = null;
                    //selProceso = null;
                    logValido = false;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
            }

        #endregion

        #region IDataErrorInfo Members

            string IDataErrorInfo.Error { get { return null; } }

            string IDataErrorInfo.this[string propertyName]
            {
                get { return this.GetValidationError(propertyName); }
            }

            #endregion

        #region Validation

            /// <summary>
            /// Returns true if this object has no validation errors.
            /// </summary>
            /// 

            public bool IsValid
            {
                get
                {
                    foreach (string property in ValidatedProperties)
                        if (GetValidationError(property) != null)
                            return false;

                    return true;
                }
            }

            static readonly string[] ValidatedProperties = 
            { 
                "SEM_NVP",
                "dtDesde",
                "dtHasta",
                "selProceso",
                "selCliente"
            };

            string GetValidationError(string propertyName)
            {
                if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                    return null;

                string error = null;

                switch (propertyName)
                {
                    case "SEM_NVP":
                        error = this.ValidateSemana();
                        break;
                    case "dtDesde":
                        error = this.ValidateDesde();
                        break;
                    case "dtHasta":
                        error = this.ValidateHasta();
                        break;
                    case "selProceso":
                        error = this.ValidateProceso();
                        break;
                    case "selCliente":
                        error = this.ValidateEmpleado();
                        break;
                    default:
                        Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                        break;
                }
                return error;
            }

            string ValidateSemana()
            {
                try
                {
                    if (SEM_NVP <= 0 || SEM_NVP > 52) { return "Debe ingresar una semana valida"; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateDesde()
            {
                try
                {
                    if (dtDesde > dtHasta) { return "La fecha inicial debe ser menor o igual que la fecha final."; }
                    TimeSpan ts = dtHasta.Subtract(dtDesde);
                    if (ts.Days > 7) { return "El rango de fechas no debe de ser mayor a una semana."; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateHasta()
            {
                try
                {
                    if (dtHasta < dtDesde) { return "La fecha final debe ser mayor o igual que la fecha inicial"; }
                    TimeSpan ts = dtHasta.Subtract(dtDesde);
                    if (ts.Days > 7) { return "El rango de fechas no debe de ser mayor a una semana."; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateProceso()
            {
                try
                {
                    if (selProceso==null) { return "Debe seleccionar algun proceso."; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateEmpleado()
            {
                try
                {
                    if (selCliente==null) { return "Debe seleccionar algun empleado."; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

        #endregion
    }


   public class VmNovedadProduccion : ViewModelBase, IDataErrorInfo
   {

        #region fields
            
            private CLSNOVPRD _novedades = new CLSNOVPRD();

        #endregion

        #region Constructor

            public VmNovedadProduccion(CLSNOVPRD novedades)
            {
                _novedades = novedades;
            }

            public VmNovedadProduccion()
            {
                agregar = true;
            }
       
        #endregion

        #region public interface

            public ValidarNovedad validarNovedad { get; set; }
            
            public int ANO_NVP
            {
                get { return _novedades.ANO_NVP; }
                set { _novedades.ANO_NVP = value; base.OnPropertyChanged("ANO_NVP"); }
            }

            public int SEM_NVP
            {
                get { return _novedades.SEM_NVP; }
                set { _novedades.SEM_NVP = value; base.OnPropertyChanged("SEM_NVP"); }
            }

            public string CODPRC_NVP
            {
                get { return _novedades.CODPRC_NVP; }
                set { _novedades.CODPRC_NVP = value; base.OnPropertyChanged("CODPRC_NVP"); }
            }

            public string CODEMP_NVP
            {
                get { return _novedades.CODEMP_NVP; }
                set { _novedades.CODEMP_NVP = value; base.OnPropertyChanged("CODEMP_NVP"); }
            }

            public int CONSEC_NVP
            {
                get { return _novedades.CONSEC_NVP; }
                set { _novedades.CONSEC_NVP = value; base.OnPropertyChanged("CONSEC_NVP"); }
            }

            public string TIPO_NVP
            {
                get { return _novedades.TIPO_NVP; }
                set { _novedades.TIPO_NVP = value; base.OnPropertyChanged("TIPO_NVP"); }
            }

            public string ESTNOV_NVP
            {
                get { return _novedades.ESTNOV_NVP; }
                set { _novedades.concepto.TIPO_CPT = value; base.OnPropertyChanged("ESTNOV_NVP"); }
            }

            public string CODCPT_NVP 
            {
                get { return _novedades.CODCPT_NVP; }
                set 
                { 
                    _novedades.CODCPT_NVP = value;
                    if (_novedades.CODCPT_NVP.Length==3)
                    {
                        ConsultarConcepto();
                        base.OnPropertyChanged("CODCPT_NVP");
                    }
                }
            }

            public string CONCEP_NVP 
            {
                get { return _novedades.concepto.NOMCPT_CPT; }
                set { _novedades.concepto.NOMCPT_CPT=value; base.OnPropertyChanged("CONCEP_NVP"); }
            }

            public double VLRNOV_NVP 
            {
                get { return _novedades.VLRNOV_NVP; }
                set 
                { 
                    _novedades.VLRNOV_NVP = value;
                    if (value != 0)
                        actualizar = true;
                    base.OnPropertyChanged("VLRNOV_NVP"); 
                }
            }

            private bool _actualizar = false;
            public bool actualizar
            {
                get { return _actualizar; }
                set { _actualizar = value; base.OnPropertyChanged("actualizar"); }
            }

            private bool _eliminar = false;
            public bool eliminar
            {
                get { return _eliminar; }
                set { _eliminar = value; base.OnPropertyChanged("eliminar"); }
            }

            private bool _agregar = false;
            public bool agregar
            {
                get { return _agregar; }
                set { _agregar = value; base.OnPropertyChanged("agregar"); }
            }
            

        #endregion

        #region methods
        
            public delegate void ValidarNovedad(); 

            void ConsultarConcepto() 
            {
                try 
                {
                    _novedades.concepto.CODCPT_CPT = CODCPT_NVP;
                    _novedades.concepto.consultar();
                    if (_novedades.concepto.NOMCPT_CPT != null)
                    {
                        _novedades.CONCEP_NVP = _novedades.concepto.NOMCPT_CPT;
                        _novedades.TIPO_NVP = (_novedades.concepto.TIPO_CPT == "P") ? "B" : _novedades.concepto.TIPO_CPT;
                        base.OnPropertyChanged("CONCEP_NVP");
                        base.OnPropertyChanged("TIPO_NVP");
                    }
                }
                catch (Exception ex) { throw ex; }
            }

            public CLSNOVPRD getNovedades()
            {
                return _novedades;
            }

        #endregion

        #region IDataErrorInfo Members

            string IDataErrorInfo.Error { get { return null; } }

            string IDataErrorInfo.this[string propertyName]
            {
                get { return this.GetValidationError(propertyName); }
            }

        #endregion

        #region Validation

            /// <summary>
            /// Returns true if this object has no validation errors.
            /// </summary>
            /// 

            public bool IsValid
            {
                get
                {
                    foreach (string property in ValidatedProperties)
                        if (GetValidationError(property) != null)
                            return false;

                    return true;
                }
            }

            static readonly string[] ValidatedProperties = 
                    { 
                        "CODCPT_NVP",
                        "CONCEP_NVP",
                        "VLRNOV_NVP"
                    };

            string GetValidationError(string propertyName)
            {
                if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                    return null;

                string error = null;
                //&& CODCPT_NVP.Length==3
                switch (propertyName)
                {
                    case "CODCPT_NVP":
                        if (CODCPT_NVP != null )
                            error = this.ValidateCodigo();
                        break;
                    case "CONCEP_NVP":
                        error = this.ValidateConcepto();
                        break;
                    case "VLRNOV_NVP":
                        error = this.ValidateValor();
                        break;
                    default:
                        Debug.Fail("Unexpected property being validated on Customer: " + propertyName);
                        break;
                }
                return error;
            }

            string ValidateCodigo()
            {
                try
                {
                    if (CODCPT_NVP==null) { return "Debe ingresar el código de la noveda."; }
                    if (CODCPT_NVP != null)
                    {
                        if (CODCPT_NVP.Length != 3)
                        {
                            if (CONCEP_NVP == null) { return "Código invalido."; }
                        }
                        else
                        {
                            if (CONCEP_NVP == null) { return "Código no existe."; }
                        }                        
                    }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateConcepto()
            {
                try
                {
                    if (CONCEP_NVP == null) { return "El código de la noveda esta errado"; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

            string ValidateValor()
            {
                try
                {
                    if (VLRNOV_NVP <= 0) { return "El valor de la novedad debe ser mayor que cero"; }

                    return null;
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                return null;
            }

        #endregion
   }
}
